<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

</body>
<script>
  // 面向对象封装
  // 1. 改写构造函数   =>解决了血缘关系  Tom instanceof Cat => true

  function Cat(name, color) {
    // {}
    // this -> {}
    this.name = name;
    this.color = color;

    // {name,color}

    // 新版本  => 不允许用户直接访问 [[prototype]]
    // this.[[prototype]] = Cat.prototype

    // 老版本
    // this.__proto__  = Cat.prototype;

    // return this;
  }


  // 2. 对象中共有的属性和方法重复声明   => 占内存

  // 原型对象(显示原型) prototype   => {constructor:f}
  // 把共有的属性和方法提取出来 放到构造函数的prototype(Cat.prototype) => 允许所有的实例化对象访问

  // console.dir(Array);  //打印 对象或函数的详细属性和方法
  // 可以理解为函数也是一个特殊的对象  Array.from


  // {constructor:f}
  // constructor 构造器属性 =>    构造函数 原型对象的默认设置属性: 指向构造函数本身   
  // 可以理解为   Cat.prototype.constructor = Cat;

  // 实际上是给所有的实例化对象使用  =>  所有的实例化对象可通过constructor属性 找到创建它的构造函数

  console.dir(Cat);  //打印 对象或函数的详细属性和方法



  // Cat.prototype.species = "cat";
  // Cat.prototype.call = function () {
  //     console.log("喵喵");
  // }
  // Cat.prototype.skill = function () {
  //     console.log("捉老鼠");
  // }

  // // 此方法虽然存在原型对象中, 但是调用时 是由实例化对象访问的 Tom.say() =>this指向调用此方法的实例化对象
  // Cat.prototype.say = function () {
  //     console.log(this.name, this.color);
  // }

  console.dir(Cat.prototype.constructor);



  var Tom = new Cat("Tom", "black");
  console.log(Tom);
  console.log(Tom.constructor === Cat);


  var Kitty = new Cat("Kitty", "pink");
  console.log(Kitty);












</script>

</html>